import pytest
import argparse
from unittest.mock import patch, MagicMock, Mock
import sys

def get_mock_modules():
    return {
        'engine_server.config.base': MagicMock(),
        'engine_server.parser.config_parser': MagicMock(),
        'engine_server.factory.core_factory': MagicMock(),
        'engine_server.utils.logger': MagicMock(),
        'engine_server.core.vllm': MagicMock(),
        'engine_server.core.vllm.vllm_core': MagicMock(),
        'engine_server.core.vllm.vllm_engine_proc_mgr': MagicMock(),
        'vllm': MagicMock(),
        'vllm.env_override': MagicMock(),
        'torch': MagicMock(),
        'transformers': MagicMock()
    }

class TestParseCliArgs:
    
    def test_parse_default_args(self):
        test_args = ["--engine-type", "vllm"]
        
        with patch('sys.argv', ['test_script.py'] + test_args):
            import argparse
            parser = argparse.ArgumentParser()
            parser.add_argument('--engine-type', required=True)
            parser.add_argument('--server-host', default='0.0.0.0')
            parser.add_argument('--server-port', type=int, default=9001)
            parser.add_argument('--config-path', default=None)
            parser.add_argument('--dp-rank', type=int, default=0)
            args = parser.parse_args()

            assert args.engine_type == "vllm"
            assert args.server_host == "0.0.0.0"
            assert args.server_port == 9001
            assert args.config_path is None
            assert args.dp_rank == 0

    def test_parse_all_custom_args(self):
        test_args = [
            "--engine-type", "tensorrt",
            "--server-host", "127.0.0.1",
            "--server-port", "9002",
            "--config-path", "./config.json",
            "--dp-rank", "1"
        ]
        
        with patch('sys.argv', ['test_script.py'] + test_args):
            import argparse
            parser = argparse.ArgumentParser()
            parser.add_argument('--engine-type', required=True)
            parser.add_argument('--server-host', default='0.0.0.0')
            parser.add_argument('--server-port', type=int, default=9001)
            parser.add_argument('--config-path', default=None)
            parser.add_argument('--dp-rank', type=int, default=0)
            args = parser.parse_args()

            assert args.engine_type == "tensorrt"
            assert args.server_host == "127.0.0.1"
            assert args.server_port == 9002
            assert args.config_path == "./config.json"
            assert args.dp_rank == 1

    def test_missing_required_engine_type(self):
        test_args = []
        
        with patch('sys.argv', ['test_script.py'] + test_args), pytest.raises(SystemExit) as excinfo:
            import argparse
            parser = argparse.ArgumentParser()
            parser.add_argument('--engine-type', required=True)
            parser.add_argument('--server-host', default='0.0.0.0')
            parser.add_argument('--server-port', type=int, default=9001)
            parser.add_argument('--config-path', default=None)
            parser.add_argument('--dp-rank', type=int, default=0)
            parser.parse_args()

        assert excinfo.value.code == 2

    def test_invalid_parameter_types(self):
        test_args = ["--engine-type", "vllm", "--server-port", "abc"]
        
        with patch('sys.argv', ['test_script.py'] + test_args), pytest.raises(SystemExit) as excinfo:
            import argparse
            parser = argparse.ArgumentParser()
            parser.add_argument('--engine-type', required=True)
            parser.add_argument('--server-host', default='0.0.0.0')
            parser.add_argument('--server-port', type=int, default=9001)
            parser.add_argument('--config-path', default=None)
            parser.add_argument('--dp-rank', type=int, default=0)
            parser.parse_args()

        assert excinfo.value.code == 2

class TestMain:
    
    def test_main_function_success(self):
        def mock_main():
            raise KeyboardInterrupt()
        
        with pytest.raises(KeyboardInterrupt):
            mock_main()

    def test_main_function_config_parser_exception(self):
        def mock_main():
            raise ValueError("Invalid configuration path")
        
        with pytest.raises(ValueError, match="Invalid configuration path"):
            mock_main()